package org.springframework.web.multipart.commons;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Part;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class Servlet3MultipartFile implements MultipartFile {

    private static final byte[] EMPTY_CONTENT = new byte[0];
    long size;
    Part part;

    public Servlet3MultipartFile(Part part) {
        this.part = part;
        this.size = part.getSize();
    }

    @Override
    public String getName() {
        return part.getName();
    }

    @Override
    public String getOriginalFilename() {
        return part.getSubmittedFileName();
    }

    @Override
    public String getContentType() {
        return part.getContentType();
    }

    @Override
    public boolean isEmpty() {
        return (this.size == 0);
    }

    @Override
    public long getSize() {
        return this.size;
    }

    @Override
    public byte[] getBytes() throws IOException {
        if (!isAvailable()) {
            throw new IllegalStateException("File has been moved - cannot be read again");
        }
        byte[] bytes = new byte[(int)size];
        this.part.getInputStream().read(bytes);
        return (bytes != null ? bytes : new byte[0]);
    }
    @Override
    public InputStream getInputStream() throws IOException {
        if (!this.isAvailable()) {
            throw new IllegalStateException("File has been moved - cannot be read again");
        } else {
            InputStream inputStream = this.part.getInputStream();
            return inputStream != null ? inputStream : new ByteArrayInputStream(EMPTY_CONTENT);
        }
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        if (!isAvailable()) {
            throw new IllegalStateException("File has already been moved - cannot be transferred again");
        }

        if (dest.exists() && !dest.delete()) {
            throw new IOException(
                    "Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");
        }

        this.part.write(dest.getAbsolutePath());

    }

    protected boolean isAvailable() {
        // Check whether current file size is different than original one.
        return (this.part.getSize() == this.size);
    }
}
